Correct CVE-2017-922[4-9]
 Fix mutilple invalid pointer dereference, out-of-bounds write memory 
 corruption and stack buffer overflow,
Origin: Cheerypicked from upstream
Bug: https://github.com/kkos/oniguruma/issues/[55|56|57|58|59|60]
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=86331[2|3|4|5|6|8]
Forwarded: not-needed
Last-Update: 2017-05-25
---
This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
Index: 6.1.3-1+deb9u1/src/regexec.c
===================================================================
--- 6.1.3-1+deb9u1.orig/src/regexec.c
+++ 6.1.3-1+deb9u1/src/regexec.c
@@ -1463,14 +1463,9 @@ match_at(regex_t* reg, const UChar* str,
       break;
 
     case OP_EXACT1:  MOP_IN(OP_EXACT1);
-#if 0
       DATA_ENSURE(1);
       if (*p != *s) goto fail;
       p++; s++;
-#endif
-      if (*p != *s++) goto fail;
-      DATA_ENSURE(0);
-      p++;
       MOP_OUT;
       break;
 
@@ -3149,6 +3144,8 @@ forward_search_range(regex_t* reg, const
     }
     else {
       UChar *q = p + reg->dmin;
+
+      if (q >= end) return 0; /* fail */
       while (p < q) p += enclen(reg->enc, p);
     }
   }
@@ -3228,18 +3225,25 @@ forward_search_range(regex_t* reg, const
     }
     else {
       if (reg->dmax != ONIG_INFINITE_DISTANCE) {
-        *low = p - reg->dmax;
-        if (*low > s) {
-          *low = onigenc_get_right_adjust_char_head_with_prev(reg->enc, s,
-                                          *low, (const UChar** )low_prev);
-          if (low_prev && IS_NULL(*low_prev))
-            *low_prev = onigenc_get_prev_char_head(reg->enc,
-                                                   (pprev ? pprev : s), *low);
-        }
-        else {
+        if (p - str < reg->dmax) {
+          *low = (UChar* )str;
           if (low_prev)
-            *low_prev = onigenc_get_prev_char_head(reg->enc,
-                                                   (pprev ? pprev : str), *low);
+            *low_prev = onigenc_get_prev_char_head(reg->enc, str, *low);
+ 	}
+ 	else {
+          *low = p - reg->dmax;
+          if (*low > s) {
+            *low = onigenc_get_right_adjust_char_head_with_prev(reg->enc, s,
+                                                 *low, (const UChar** )low_prev);
+            if (low_prev && IS_NULL(*low_prev))
+              *low_prev = onigenc_get_prev_char_head(reg->enc,
+                                                     (pprev ? pprev : s), *low);
+          }
+          else {
+            if (low_prev)
+              *low_prev = onigenc_get_prev_char_head(reg->enc,
+                                                     (pprev ? pprev : str), *low);
+          }
         }
       }
     }
Index: 6.1.3-1+deb9u1/src/regparse.c
===================================================================
--- 6.1.3-1+deb9u1.orig/src/regparse.c
+++ 6.1.3-1+deb9u1/src/regparse.c
@@ -2986,7 +2986,7 @@ fetch_token_in_cc(OnigToken* tok, UChar*
         PUNFETCH;
         prev = p;
         num = scan_unsigned_octal_number(&p, end, 3, enc);
-        if (num < 0) return ONIGERR_TOO_BIG_NUMBER;
+        if (num < 0 || num >= 256) return ONIGERR_TOO_BIG_NUMBER;
         if (p == prev) {  /* can't read nothing. */
           num = 0; /* but, it's not error */
         }
@@ -3358,7 +3358,7 @@ fetch_token(OnigToken* tok, UChar** src,
       if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_OCTAL3)) {
         prev = p;
         num = scan_unsigned_octal_number(&p, end, (c == '0' ? 2:3), enc);
-        if (num < 0) return ONIGERR_TOO_BIG_NUMBER;
+        if (num < 0 || num >= 256) return ONIGERR_TOO_BIG_NUMBER;
         if (p == prev) {  /* can't read nothing. */
           num = 0; /* but, it's not error */
         }
@@ -3994,7 +3994,9 @@ next_state_class(CClassNode* cc, OnigCod
     }
   }
 
-  *state = CCS_VALUE;
+  if (*state != CCS_START)
+    *state = CCS_VALUE;
+
   *type  = CCV_CLASS;
   return 0;
 }
@@ -4010,6 +4012,9 @@ next_state_val(CClassNode* cc, OnigCodeP
   switch (*state) {
   case CCS_VALUE:
     if (*type == CCV_SB) {
+      if (*vs > 0xff)
+          return ONIGERR_INVALID_CODE_POINT_VALUE;
+
       BITSET_SET_BIT(cc->bs, (int )(*vs));
     }
     else if (*type == CCV_CODE_POINT) {
Index: 6.1.3-1+deb9u1/src/gperf_unfold_key_conv.py
===================================================================
--- 6.1.3-1+deb9u1.orig/src/gperf_unfold_key_conv.py
+++ 6.1.3-1+deb9u1/src/gperf_unfold_key_conv.py
@@ -36,7 +36,7 @@ def parse_line(s):
     if r != s: return r
     r = re.sub(REG_GET_CODE, 'OnigCodePoint gcode = wordlist[key].code;', s)
     if r != s: return r
-    r = re.sub(REG_CODE_CHECK, 'if (code == gcode)', s)
+    r = re.sub(REG_CODE_CHECK, 'if (code == gcode && wordlist[key].index >= 0)', s)
     if r != s: return r
 
     return s
Index: 6.1.3-1+deb9u1/src/unicode_unfold_key.c
===================================================================
--- 6.1.3-1+deb9u1.orig/src/unicode_unfold_key.c
+++ 6.1.3-1+deb9u1/src/unicode_unfold_key.c
@@ -2844,7 +2844,7 @@ unicode_unfold_key(OnigCodePoint code)
         {
           OnigCodePoint gcode = wordlist[key].code;
 
-          if (code == gcode)
+          if (code == gcode && wordlist[key].index >= 0)
             return &wordlist[key];
         }
     }